
# ifndef __DFX_RENDER_STATE_H__
# define __DFX_RENDER_STATE_H__

# include "dfxCore.h"
# include "dfxColor4.h"

namespace DFX
{
    enum BLEND_OPTION
    {
        BLEND_OPTION_ZERO,
        BLEND_OPTION_ONE,
        BLEND_OPTION_SRC_COLOR,
        BLEND_OPTION_ONE_MINUS_SRC_COLOR,
        BLEND_OPTION_DEST_COLOR,
        BLEND_OPTION_ONE_MINUS_DEST_COLOR,
        BLEND_OPTION_SRC_ALPHA,
        BLEND_OPTION_ONE_MINUS_SRC_ALPHA,
        BLEND_OPTION_DEST_ALPHA,
        BLEND_OPTION_ONE_MINUS_DEST_ALPHA,
        BLEND_OPTION_SRC_ALPHA_SATURATE,
        BLEND_OPTION_COUNT
    };

    enum BLEND_EQUATION
    {
        BLEND_EQUATION_ADD,
        BLEND_EQUATION_SUBTRACT,
        BLEND_EQUATION_REV_SUBTRACT,
        BLEND_EQUATION_MIN,
        BLEND_EQUATION_MAX,
        BLEND_EQUATION_COUNT
    };

    enum COLOR_MASK
    {
        COLOR_MASK_RED = 0x1,
        COLOR_MASK_GREEN = 0x2,
        COLOR_MASK_BLUE = 0x4,
        COLOR_MASK_ALPHA = 0x8,
        COLOR_MASK_ALL = 0xF
    };

    enum COMPARE_FUNCTION
    {
        COMPARE_FUNCTION_NEVER,
        COMPARE_FUNCTION_LESS,
        COMPARE_FUNCTION_LESS_OR_EQUAL,
        COMPARE_FUNCTION_GREATER,
        COMPARE_FUNCTION_GREATER_OR_EQUAL,
        COMPARE_FUNCTION_EQUAL,
        COMPARE_FUNCTION_NOT_EQUAL,
        COMPARE_FUNCTION_ALWAYS,
        COMPARE_FUNCTION_COUNT
    };

    enum STENCIL_OPTION
    {
        STENCIL_OPTION_KEEP,
        STENCIL_OPTION_ZERO,
        STENCIL_OPTION_REPLACE,
        STENCIL_OPTION_INCREMENT,
        STENCIL_OPTION_DECREMENT,
        STENCIL_OPTION_INVERT,
        STENCIL_OPTION_INCREMENT_WRAP,
        STENCIL_OPTION_DECREMENT_WRAP,
        STENCIL_OPTION_COUNT
    };

    enum STENCIL_FACE
    {
        STENCIL_FACE_FRONT,
        STENCIL_FACE_BACK,
        STENCIL_FACE_FRONT_BACK,
        STENCIL_FACE_COUNT
    };

    enum CULL_MODE
    {
        CULL_MODE_CLOCKWISE,
        CULL_MODE_COUNTER_CLOCKWISE,
        CULL_MODE_NONE,
        CULL_MODE_COUNT
    };

    enum FILL_MODE
    {
        FILL_MODE_POINT,
        FILL_MODE_SOLID,
        FILL_MODE_WIREFRAME,
        FILL_MODE_COUNT
    };

    class DFX_EXPORT AlphaStateDescription
    {
    public:

        bool                BlendEnabled;
        bool                AlphaTestEnabled;
        BLEND_OPTION        SourceBlend;
        BLEND_OPTION        DestinationBlend;
        COMPARE_FUNCTION    AlphaFunction;
        BLEND_EQUATION      BlendEquation;
        Float32             Reference;
        Color4              ConstantColor;

    public:

        AlphaStateDescription()
        {
        }
    };

    class DFX_EXPORT RasterizerStateDescription
    {
    public:

        CULL_MODE   CullMode;
        FILL_MODE   FillMode;

    public:

        RasterizerStateDescription()
        {
        }
    };

    class DFX_EXPORT DepthStateDescription
    {
    public:

        bool                Enabled;
        bool                Writable;
        COMPARE_FUNCTION    CompareFunction;

    public:

        DepthStateDescription()
        {
        }
    };

    class DFX_EXPORT StencilStateDescription
    {
    public:

        bool                Enabled;
        STENCIL_FACE        Face;
        COMPARE_FUNCTION    CompareFunction;
        UInt32              Reference;
        UInt32              Mask;
        UInt32              WriteMask;
        STENCIL_OPTION      OnFail;
        STENCIL_OPTION      OnZFail;
        STENCIL_OPTION      OnZPass;

    public:

        StencilStateDescription()
        {
        }
    };

    class DFX_EXPORT RenderState
    {
    public:

        virtual void Apply() = 0;
    };

    class DFX_EXPORT AlphaState : public RenderState
    {
    protected:

        AlphaStateDescription   mDescription;

    public:

        AlphaState(const AlphaStateDescription &desc)
            : mDescription(desc)
        {
        }

        virtual ~AlphaState()
        {
        }

        const AlphaStateDescription& GetDescription() const
        {
            return mDescription;
        }
    };

    class DFX_EXPORT RasterizerState : public RenderState
    {
    protected:

        RasterizerStateDescription mDescription;

    public:

        RasterizerState(const RasterizerStateDescription &desc)
            : mDescription(desc)
        {
        }

        const RasterizerStateDescription& GetDescription() const
        {
            return mDescription;
        }
    };

    class DFX_EXPORT DepthState : public RenderState
    {
    protected:

        DepthStateDescription   mDescription;

    public:

        DepthState(const DepthStateDescription &desc)
            : mDescription(desc)
        {
        }

        const DepthStateDescription& GetDescription() const
        {
            return mDescription;
        }
    };

    class DFX_EXPORT StencilState : public RenderState
    {
    protected:

        StencilStateDescription     mDescription;

    public:

        StencilState(const StencilStateDescription &desc)
            : mDescription(desc)
        {
        }

        const StencilStateDescription& GetDescription() const
        {
            return mDescription;
        }
    };
}

# endif